home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: TS3Sound.c
- * Author: Dan Venolia
- *
- * Contents: Handles some of the sound stuff.
- *
- * Copyright © 1996 Apple Computer, Inc.
- */
-
- #include <assert.h>
- #include <math.h>
- #include <stdio.h>
- #include <string.h>
-
- #include <Controls.h>
- #include <Dialogs.h>
- #include <Sound.h>
- #include <Resources.h>
- #include <Timer.h>
-
- #include "SoundSprocket.h"
-
- #include "TS3Resource.h"
- #include "TS3Sound.h"
- #include "TS3Utils.h"
- #include "TS3Window.h"
-
- static SndChannelPtr gSoundChannel = NULL;
- static SndListHandle gSoundResource = NULL;
- static DialogPtr gSoundDialog = NULL;
- static UserItemUPP gSoundBoxUserItemProc = NULL;
- static Snd3DInfo gSoundPrev3DInfo;
-
-
- static WindowMethodPtr Sound_MetaHandler(
- WindowMethod inMethod);
-
- static void Sound_ConsumeEvent(
- WindowPtr inWindow,
- const EventRecord* inEvent,
- Boolean* outConsumed);
-
- static pascal void Sound_BoxUserItem(
- DialogPtr inDialog,
- short inItem);
-
-
- /* =============================================================================
- * Sound_Init (external)
- *
- * Initializes the sound stuff.
- * ========================================================================== */
- void Sound_Init(
- void)
- {
- SoundComponentLink link;
-
- assert(kFeedbackItem_COUNT == kFeedbackItem_ExpectedCount);
-
- // Allocate the sound channel
- SndNewChannel(&gSoundChannel, sampledSynth, initMono, NULL);
- assert(gSoundChannel != NULL);
-
- // Install the 3D sound filters
- link.description.componentType = kSoundEffectsType;
- link.description.componentSubType = kSnd3DSubType;
- link.description.componentManufacturer = 'appl';
- link.description.componentFlags = 0;
- link.description.componentFlagsMask = 0;
- link.mixerID = nil;
- link.linkID = nil;
-
- SndSetInfo(gSoundChannel, siPreMixerSoundComponent, &link);
-
- // Set up the user item UPP
- gSoundBoxUserItemProc = NewUserItemProc(Sound_BoxUserItem);
- assert(gSoundBoxUserItemProc != NULL);
-
- // Grab the dialog
- gSoundDialog = GetNewDialog(kDlogID_Feedback, NULL, (WindowPtr) -1);
- assert(gSoundDialog != NULL);
-
- // Set up our method table
- Window_New(gSoundDialog, Sound_MetaHandler);
-
- // Show the dialog
- ShowWindow(gSoundDialog);
-
- // Initialize the Snd3DInfo state to garbage
- memset(&gSoundPrev3DInfo, 0x55, sizeof(Snd3DInfo));
- }
-
-
- /* =============================================================================
- * Sound_Exit (external)
- *
- * Prepares for exit.
- * ========================================================================== */
- void Sound_Exit(
- void)
- {
- Sound_PlaySilence();
- assert(gSoundResource == NULL);
-
- if (gSoundChannel != NULL)
- {
- SndDisposeChannel(gSoundChannel, true);
- gSoundChannel = NULL;
- }
-
- if (gSoundBoxUserItemProc != NULL)
- {
- DisposeRoutineDescriptor(gSoundBoxUserItemProc);
- gSoundBoxUserItemProc = NULL;
- }
-
- if (gSoundDialog != NULL)
- {
- DisposeDialog(gSoundDialog);
- gSoundDialog = NULL;
- }
- }
-
-
- /* =============================================================================
- * Sound_MetaHandler (internal)
- *
- * Returns the method function pointer that corresponds to the given ID.
- * ========================================================================== */
- WindowMethodPtr Sound_MetaHandler(
- WindowMethod inMethod)
- {
- WindowMethodPtr result;
-
- result = NULL;
-
- switch (inMethod)
- {
- case kWindowMethod_ConsumeEvent:
- result = Sound_ConsumeEvent;
- break;
- }
-
- return result;
- }
-
-
- /* =============================================================================
- * Sound_ConsumeEvent (internal)
- *
- * Called for each event when this is the front window.
- * ========================================================================== */
- void Sound_ConsumeEvent(
- WindowPtr inWindow,
- const EventRecord* inEvent,
- Boolean* outConsumed)
- {
- Boolean consumed;
- WindowPtr window;
- short item;
-
- assert(inEvent != NULL);
- assert(outConsumed != NULL);
-
- consumed = false;
-
- // Do dialog stuff
- if (inEvent->what != keyDown || (inEvent->modifiers & cmdKey) == 0)
- {
- consumed = IsDialogEvent(inEvent);
- if (consumed)
- {
- DialogSelect(inEvent, &window, &item);
- }
- }
-
- // Return the result
- *outConsumed = consumed;
- }
-
-
- /* =============================================================================
- * Sound_PlaySilence (external)
- *
- * Stops any sound that is playing.
- * ========================================================================== */
- void Sound_PlaySilence(
- void)
- {
- SndCommand sndCommand;
-
- sndCommand.cmd = quietCmd;
- sndCommand.param1 = 0;
- sndCommand.param2 = 0;
- SndDoImmediate(gSoundChannel, &sndCommand);
-
- if (gSoundResource != NULL)
- {
- ReleaseResource((Handle) gSoundResource);
- gSoundResource = NULL;
- }
- }
-
-
- /* =============================================================================
- * Sound_PlayResource (external)
- *
- * Plays the 'snd ' resource that has the given name. Returns true if
- * successful; returns false if unsuccessful and therefore silence is happening.
- * ========================================================================== */
- Boolean Sound_PlayResource(
- Str255 inSndName)
- {
- SndCommand sndCommand;
- long offset;
-
- // Silence the sound channel and get rid of the old resource
- Sound_PlaySilence();
-
- // Grab the resource
- gSoundResource = (SndListHandle) GetNamedResource('snd ', inSndName);
- if (gSoundResource == NULL || ResError() != noErr)
- {
- StopAlert(kAlrtID_BadSndLoad, NULL);
- goto bail;
- }
-
- // Lock it down
- HLockHi((Handle) gSoundResource);
-
- // Play it indefinitely
- GetSoundHeaderOffset(gSoundResource, &offset);
-
- sndCommand.cmd = soundCmd;
- sndCommand.param1 = 0;
- sndCommand.param2 = (long) *gSoundResource + offset;
- SndDoImmediate(gSoundChannel, &sndCommand);
-
- sndCommand.cmd = freqCmd;
- sndCommand.param1 = 0;
- sndCommand.param2 = 60;
- SndDoImmediate(gSoundChannel, &sndCommand);
-
- return true;
-
- // Error exit
- bail:
- if (gSoundResource != NULL)
- {
- ReleaseResource((Handle) gSoundResource);
- gSoundResource = NULL;
- }
-
- return false;
- }
-
-
- /* =============================================================================
- * Sound_Set3DInfo (external)
- *
- * Sends the given 3D info to the sound channel.
- * ========================================================================== */
- void Sound_Set3DInfo(
- const Snd3DInfo* in3DInfo)
- {
- Str255 str;
- UnsignedWide time;
-
- static UnsignedWide prevTime = {0, 0};
-
- assert(in3DInfo != NULL);
-
- // Change the filter
- SndSetInfo(gSoundChannel, si3DInfo, (Snd3DInfo*) in3DInfo);
- //• CHECK ERROR
-
- // Update the dialog
- Microseconds(&time);
-
- Utils_SetUInt32Field(
- gSoundDialog,
- kFeedbackItem_Updates,
- 1000000.0 / (time.lo-prevTime.lo),
- true);
-
- prevTime = time;
-
- if (gSoundPrev3DInfo.cpuLoad != in3DInfo->cpuLoad)
- {
- Utils_SetUInt32Field(
- gSoundDialog,
- kFeedbackItem_CPULoad,
- in3DInfo->cpuLoad,
- true);
-
- gSoundPrev3DInfo.cpuLoad = in3DInfo->cpuLoad;
- }
-
- if (gSoundPrev3DInfo.medium != in3DInfo->medium)
- {
- switch (in3DInfo->medium)
- {
- case kMediumAir:
- strcpy((char*) str, (char*) "\pkMediumAir");
- break;
-
- case kMediumWater:
- strcpy((char*) str, (char*) "\pkMediumWater");
- break;
-
- default:
- sprintf((char*) str, "x<<%lu>>", (unsigned long) in3DInfo->medium);
- str[0] = strlen((char*) str) - 1;
- }
-
- Utils_SetStr255Field(
- gSoundDialog,
- kFeedbackItem_Medium,
- str,
- true);
-
- gSoundPrev3DInfo.medium = in3DInfo->medium;
- }
-
- if (gSoundPrev3DInfo.humidity != in3DInfo->humidity)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Humidity,
- in3DInfo->humidity,
- true);
-
- gSoundPrev3DInfo.humidity = in3DInfo->humidity;
- }
-
- if (gSoundPrev3DInfo.roomSize != in3DInfo->roomSize)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_RoomSize,
- in3DInfo->roomSize,
- true);
-
- gSoundPrev3DInfo.roomSize = in3DInfo->roomSize;
- }
-
- if (gSoundPrev3DInfo.roomReflectivity != in3DInfo->roomReflectivity)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_RoomReflectivity,
- in3DInfo->roomReflectivity,
- true);
-
- gSoundPrev3DInfo.roomReflectivity = in3DInfo->roomReflectivity;
- }
-
- if (gSoundPrev3DInfo.reverbAttenuation != in3DInfo->reverbAttenuation)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_ReverbAttenuation,
- in3DInfo->reverbAttenuation,
- true);
-
- gSoundPrev3DInfo.reverbAttenuation = in3DInfo->reverbAttenuation;
- }
-
- if (gSoundPrev3DInfo.sourceMode != in3DInfo->sourceMode)
- {
- switch (in3DInfo->sourceMode)
- {
- case kSourceModeLocalized:
- strcpy((char*) str, (char*) "\pkSourceModeLocalized");
- break;
-
- case kSourceModeAmbient:
- strcpy((char*) str, (char*) "\pkSourceModeAmbient");
- break;
-
- case kSourceModeBinaural:
- strcpy((char*) str, (char*) "\pkSourceModeBinaural");
- break;
-
- default:
- sprintf((char*) str, "x<<%lu>>", (unsigned long) in3DInfo->sourceMode);
- str[0] = strlen((char*) str) - 1;
- }
-
- Utils_SetStr255Field(
- gSoundDialog,
- kFeedbackItem_SourceMode,
- str,
- true);
-
- gSoundPrev3DInfo.sourceMode = in3DInfo->sourceMode;
- }
-
- if (gSoundPrev3DInfo.referenceDistance != in3DInfo->referenceDistance)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_ReferenceDistance,
- in3DInfo->referenceDistance,
- true);
-
- gSoundPrev3DInfo.referenceDistance = in3DInfo->referenceDistance;
- }
-
- if (gSoundPrev3DInfo.coneAngleCos != in3DInfo->coneAngleCos)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_ConeAngleCos,
- in3DInfo->coneAngleCos,
- true);
-
- gSoundPrev3DInfo.coneAngleCos = in3DInfo->coneAngleCos;
- }
-
- if (gSoundPrev3DInfo.coneAttenuation != in3DInfo->coneAttenuation)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_ConeAttenuation,
- in3DInfo->coneAttenuation,
- true);
-
- gSoundPrev3DInfo.coneAttenuation = in3DInfo->coneAttenuation;
- }
-
- if (gSoundPrev3DInfo.currentLocation.longitude != in3DInfo->currentLocation.longitude)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Longitude,
- in3DInfo->currentLocation.longitude,
- true);
-
- gSoundPrev3DInfo.currentLocation.longitude = in3DInfo->currentLocation.longitude;
- }
-
- if (gSoundPrev3DInfo.currentLocation.latitude != in3DInfo->currentLocation.latitude)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Latitude,
- in3DInfo->currentLocation.latitude,
- true);
-
- gSoundPrev3DInfo.currentLocation.latitude = in3DInfo->currentLocation.latitude;
- }
-
- if (gSoundPrev3DInfo.currentLocation.distance != in3DInfo->currentLocation.distance)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Distance,
- in3DInfo->currentLocation.distance,
- true);
-
- gSoundPrev3DInfo.currentLocation.distance = in3DInfo->currentLocation.distance;
- }
-
- if (gSoundPrev3DInfo.currentLocation.projectionAngle != in3DInfo->currentLocation.projectionAngle)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_ProjectionAngle,
- in3DInfo->currentLocation.projectionAngle,
- true);
-
- gSoundPrev3DInfo.currentLocation.projectionAngle = in3DInfo->currentLocation.projectionAngle;
- }
-
- if (gSoundPrev3DInfo.currentLocation.sourceVelocity != in3DInfo->currentLocation.sourceVelocity)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_SourceVelocity,
- in3DInfo->currentLocation.sourceVelocity,
- true);
-
- gSoundPrev3DInfo.currentLocation.sourceVelocity = in3DInfo->currentLocation.sourceVelocity;
- }
-
- if (gSoundPrev3DInfo.currentLocation.listenerVelocity != in3DInfo->currentLocation.listenerVelocity)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_ListenerVelocity,
- in3DInfo->currentLocation.listenerVelocity,
- true);
-
- gSoundPrev3DInfo.currentLocation.listenerVelocity = in3DInfo->currentLocation.listenerVelocity;
- }
-
- if (gSoundPrev3DInfo.reserved0 != in3DInfo->reserved0)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Reserved0,
- in3DInfo->reserved0,
- true);
-
- gSoundPrev3DInfo.reserved0 = in3DInfo->reserved0;
- }
-
- if (gSoundPrev3DInfo.reserved1 != in3DInfo->reserved1)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Reserved1,
- in3DInfo->reserved1,
- true);
-
- gSoundPrev3DInfo.reserved1 = in3DInfo->reserved1;
- }
-
- if (gSoundPrev3DInfo.reserved2 != in3DInfo->reserved2)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Reserved2,
- in3DInfo->reserved2,
- true);
-
- gSoundPrev3DInfo.reserved2 = in3DInfo->reserved2;
- }
-
- if (gSoundPrev3DInfo.reserved3 != in3DInfo->reserved3)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_Reserved3,
- in3DInfo->reserved3,
- true);
-
- gSoundPrev3DInfo.reserved3 = in3DInfo->reserved3;
- }
-
- if (gSoundPrev3DInfo.virtualSourceCount != in3DInfo->virtualSourceCount)
- {
- Utils_SetFloatField(
- gSoundDialog,
- kFeedbackItem_VirtualSourceCount,
- in3DInfo->virtualSourceCount,
- true);
-
- gSoundPrev3DInfo.virtualSourceCount = in3DInfo->virtualSourceCount;
- }
- }
-
-
- /* =============================================================================
- * Sound_Configure (external)
- *
- * Presents the modal dialog to configure the 3D sound stuff.
- * ========================================================================== */
- void Sound_Configure(
- void)
- {
- DialogPtr dialog;
- short itemType;
- Handle itemHandle;
- Rect itemBounds;
- ControlHandle stereoControl;
- ControlHandle monoControl;
- ControlHandle headphonesControl;
- ControlHandle angleControl;
- Snd3DSetup snd3DInitialSetup;
- Snd3DSetup snd3DSetup;
- Boolean changed;
- Boolean ok;
- short item;
-
- // Grab the dialog
- dialog = GetNewDialog(kDlogID_Config3DSound, NULL, (WindowPtr) -1);
- assert(dialog != NULL);
-
- // Grab the control handles
- GetDialogItem(dialog, kConfig3DSoundItem_Stereo, &itemType, &itemHandle, &itemBounds);
- stereoControl = (ControlHandle) itemHandle;
-
- GetDialogItem(dialog, kConfig3DSoundItem_Mono, &itemType, &itemHandle, &itemBounds);
- monoControl = (ControlHandle) itemHandle;
-
- GetDialogItem(dialog, kConfig3DSoundItem_Headphones, &itemType, &itemHandle, &itemBounds);
- headphonesControl = (ControlHandle) itemHandle;
-
- GetDialogItem(dialog, kConfig3DSoundItem_Angle, &itemType, &itemHandle, &itemBounds);
- angleControl = (ControlHandle) itemHandle;
-
- // Do the user items
- GetDialogItem(dialog, kConfig3DSoundItem_SetupBox, &itemType, &itemHandle, &itemBounds);
- SetDialogItem(dialog, kConfig3DSoundItem_SetupBox, itemType, (Handle) gSoundBoxUserItemProc, &itemBounds);
-
- GetDialogItem(dialog, kConfig3DSoundItem_AngleBox, &itemType, &itemHandle, &itemBounds);
- SetDialogItem(dialog, kConfig3DSoundItem_AngleBox, itemType, (Handle) gSoundBoxUserItemProc, &itemBounds);
-
- GetDialogItem(dialog, kConfig3DSoundItem_OKHilite, &itemType, &itemHandle, &itemBounds);
- SetDialogItem(dialog, kConfig3DSoundItem_OKHilite, itemType, (Handle) Utils_GetOKUserItemProc(), &itemBounds);
-
- // Get the initial state of the setup
- SndGetInfo(gSoundChannel, si3DSetup, &snd3DSetup);
- snd3DInitialSetup = snd3DSetup;
-
- // Process events
- changed = true;
- ok = true;
- do
- {
- // Update the dialog
- if (changed)
- {
- SetControlValue(stereoControl, snd3DSetup.speakerKind == kSpeakerKindStereo);
- SetControlValue(monoControl, snd3DSetup.speakerKind == kSpeakerKindMono);
- SetControlValue(headphonesControl, snd3DSetup.speakerKind == kSpeakerKindHeadphones);
- SetControlValue(angleControl, snd3DSetup.speakerAngle * 180.0 / _PI);
-
- HiliteControl(angleControl, (snd3DSetup.speakerKind == kSpeakerKindStereo) ? 0 : 255);
-
- changed = false;
- }
-
- // Grab the next dialog event
- ModalDialog(NULL, &item);
-
- // Process the dialog item
- switch (item)
- {
- case kConfig3DSoundItem_OK:
- ok = false;
- break;
-
- case kConfig3DSoundItem_Cancel:
- snd3DSetup = snd3DInitialSetup;
- changed = true;
- ok = false;
- break;
-
- case kConfig3DSoundItem_Stereo:
- snd3DSetup.speakerKind = kSpeakerKindStereo;
- changed = true;
- break;
-
- case kConfig3DSoundItem_Mono:
- snd3DSetup.speakerKind = kSpeakerKindMono;
- changed = true;
- break;
-
- case kConfig3DSoundItem_Headphones:
- snd3DSetup.speakerKind = kSpeakerKindHeadphones;
- changed = true;
- break;
-
- case kConfig3DSoundItem_Angle:
- snd3DSetup.speakerAngle = GetControlValue(angleControl) * _PI / 180.0;
- changed = true;
- break;
- }
-
- // Update the sound channel
- if (changed)
- {
- SndSetInfo(gSoundChannel, si3DSetup, &snd3DSetup);
- }
- }
- while (ok);
-
- // Take down the dialog
- DisposDialog(dialog);
- }
-
-
- /* =============================================================================
- * Sound_BoxUserItem (internal)
- *
- * Draws the user item by framing it with a gray box.
- * ========================================================================== */
- pascal void Sound_BoxUserItem(
- DialogPtr inDialog,
- short inItem)
- {
- short itemType;
- Handle itemHandle;
- Rect itemBounds;
- RGBColor color;
-
- GetDialogItem(inDialog, inItem, &itemType, &itemHandle, &itemBounds);
-
- color.red =
- color.green =
- color.blue = 0x7777;
-
- RGBForeColor(&color);
-
- FrameRect(&itemBounds);
-
- color.red =
- color.green =
- color.blue = 0x0000;
-
- RGBForeColor(&color);
- }
-
-
-